
import java.awt.Color;

import java.awt.Font;
import java.awt.Graphics;

import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;


import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.JFrame;


public class SameGame extends JFrame{
	
	public int zestawy = 0;
	Font f = new Font("Calibri", Font.BOLD, 30);
	boolean sendScores;
	String name;
	Image imageA, imageB, imageC, imageD, imageAPress, imageBPress,
			imageCPress, imageDPress, imageE, imageEPress, imageNewGame,
			imageBlocks;

	char position[][] = new char[21][10];
	int score, clickScore, clicks, left;
	int temp, i, j, clickx, clicky, count, blinkflag, displaycount,x,y;
	int firstzeroX, lastABCDX, successX, havezeroX, countzeroX;
	int firstzeroY, lastABCDY, successY, havezeroY, countzeroY;

	double rN;
	AudioInputStream ClickSoundInput, ReduceSoundInput;
	Clip ClickSound, ReduceSound;
	
	URL url,urlClickSound,urlReduceSound;

	public void zestaw(int ile) {
		Graphics g = getGraphics();
		g.clearRect(0, 0, 700, 400);
		int wlasciwe = ile % 7;
		wlasciwe++;
		url = getClass().getResource(wlasciwe + "/imagea.gif");
		imageA = getToolkit().getImage(url);
		url = getClass().getResource(wlasciwe + "/imageapress.gif");
		imageAPress = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imageb.gif");
		imageB = getToolkit().getImage(url);
		url = getClass().getResource(wlasciwe + "/imagebpress.gif");
		imageBPress = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imagec.gif");
		imageC = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imagecpress.gif");
		imageCPress = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imaged.gif");
		imageD = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imagedpress.gif");
		imageDPress = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imagee.gif");
		imageE = getToolkit().getImage(url); 
		url = getClass().getResource(wlasciwe + "/imageepress.gif");
		imageEPress = getToolkit().getImage(url);
	}

	private static final long serialVersionUID = 1L;

	public SameGame(String string) {
		super(string);
		 MouseListener mouseD = new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent arg0) {mouseDown(arg0.getX(),arg0.getY());}
			@Override
			public void mouseEntered(MouseEvent arg0) {}
			@Override
			public void mouseExited(MouseEvent arg0) {}
			@Override
			public void mousePressed(MouseEvent arg0) {}
			@Override
			public void mouseReleased(MouseEvent arg0) {}
		    };
		    addMouseListener(mouseD);
	}
public void init2() {

		score = 0;
		for (int i9 = 0; i9 <= 9; i9++) {
			position[20][i9] = '0';
		}
		sendScores = true;
		displaycount = 0;
		clicks = 0;
		left = 0;
		clickScore = 0;
		count = 0;
		name = "";

		setBackground(Color.white);
		zestaw(zestawy);
		url = getClass().getResource("newgame.gif");
		imageNewGame = getToolkit().getImage(url);
		url = getClass().getResource("blocks.gif");
		imageBlocks = getToolkit().getImage(url);
      
		urlClickSound = getClass().getResource("click.wav");
		urlReduceSound = getClass().getResource("reduce.wav");

		for (i = 0; i <= 9; i++) {
			for (j = 0; j <= 19; j++) {
				rN = Math.random();
				if (rN < 0.20)
					position[j][i] = 'A';
				else if (rN >= 0.20 && rN < 0.40)
					position[j][i] = 'B';
				else if (rN >= 0.40 && rN < 0.60)
					position[j][i] = 'C';
				if (rN >= 0.60 && rN < 0.80)
					position[j][i] = 'D';
				if (rN >= 0.80)
					position[j][i] = 'E';
			}
		}
	}

	public void update(Graphics g) {
		paint(g);
	}

	public void paint(Graphics g) {
		g.setColor(Color.white);
		for (i = 0; i <= 9; i++) {
			for (j = 0; j <= 19; j++) {

				switch (position[j][i]) {
				case 'A':
					g.drawImage(imageA, ((j * 30) + 1)+2, ((i * 30) + 1)+20, 30, 30,
							this);
					break;
				case 'B':
					g.drawImage(imageB, ((j * 30) + 1)+2, ((i * 30) + 1)+20, 30, 30,
							this);
					break;
				case 'C':
					g.drawImage(imageC, ((j * 30) + 1)+2, ((i * 30) + 1)+20, 30, 30,
							this);
					break;
				case 'D':
					g.drawImage(imageD, ((j * 30) + 1)+2, ((i * 30) + 1)+20, 30, 30,
							this);
					break;
				case 'E':
					g.drawImage(imageE, ((j * 30) + 1)+2, ((i * 30) + 1)+20, 30, 30,
							this);
					break;
				case '1':
					g.drawImage(imageAPress, ((j * 30) + 1)+2, ((i * 30) + 1)+20,
							30, 30, this);
					break;
				case '2':
					g.drawImage(imageBPress, ((j * 30) + 1)+2, ((i * 30) + 1)+20,
							30, 30, this);
					break;
				case '3':
					g.drawImage(imageCPress, ((j * 30) + 1)+2, ((i * 30) + 1)+20,
							30, 30, this);
					break;
				case '4':
					g.drawImage(imageDPress, ((j * 30) + 1)+2, ((i * 30) + 1)+20,
							30, 30, this);
					break;
				case '5':
					g.drawImage(imageEPress, ((j * 30) + 1)+2, ((i * 30) + 1)+20,
							30, 30, this);
					break;
				case '0':
					g.fillRect((j * 30) + 1+2, (i * 30) + 1+20, 30, 30);
					break;
				}
			}
		}

		g.setColor(Color.black);
		g.fillRect(0+2, 325, 600, 50);
		g.drawImage(imageNewGame, 5+2, 330, 100, 40, this);
		g.drawImage(imageBlocks, 120+2, 330, 100, 40, this);

		Font f = new Font("Calibri", Font.BOLD, 20);
		g.setFont(f);

		g.setColor(Color.white);
		g.drawString("SCORE", 455+2, 355);
		g.drawString(String.valueOf(score), 515+2, 355);

		if (count == 0)
			displaycount = 0;
		else
			displaycount = count + 1;

		g.drawString("THIS TOTAL", 250+2, 345);
		g.drawString(String.valueOf(displaycount), 410+2, 345);
		g.drawString("THIS CLICK SCORE", 250+2, 365);
		g.drawString(String.valueOf(clickScore), 410+2, 365);

		if (endgame() == false) {
			f = new Font("Calibri", Font.BOLD, 70);
			g.setFont(f);
			g.setColor(Color.black);
			g.drawString("GAME OVER", 100, 100);
			if (sendScores) {				
				left = countLeft();
				dbConn(clicks, left, score);
				sendScores = false;
			}
		}
	}

	public int countLeft() {
		int l = 0;
		for (i = 0; i <= 9; i++) {
			for (j = 0; j <= 19; j++) {
				if (position[j][i] == '0')
					l++;}}
		return 200 - l;
	}

	public boolean mouseDown( int x, int y) {

		if (x >= 5+2 && x <= 105+2 && y >= 330 && y <= 370) {
			init2();
			repaint();
			return true;
		}
		if (x >= 120+2 && x <= 220+2 && y >= 330 && y <= 370) {
			zestaw(++zestawy);
			repaint();
			return true;
		}

		clickx = (x-2) / 30;
		clicky = (y-20) / 30;

		if ((position[clickx][clicky] >= 'A' && position[clickx][clicky] <= 'E')
				|| (position[clickx][clicky] == '0')) {
			if (blinkflag == 1) {
				for (i = 0; i <= 9; i++) {
					for (j = 0; j <= 19; j++) {
						switch (position[j][i]) {
						case '1': {
							position[j][i] = 'A';
							break;
						}
						case '2': {
							position[j][i] = 'B';
							break;
						}
						case '3': {
							position[j][i] = 'C';
							break;
						}
						case '4': {
							position[j][i] = 'D';
							break;
						}
						case '5': {
							position[j][i] = 'E';
							break;
						}}
						blinkflag = 0;
					}
				}
			}
			if (position[clickx][clicky] != '0') {
				count = 0;
				findconnect(clickx, clicky, position[clickx][clicky]);
				if (count > 0) {
			        try{			           	
				        ClickSoundInput = AudioSystem.getAudioInputStream(urlClickSound);
				        ClickSound = AudioSystem.getClip();
				        ClickSound.open(ClickSoundInput);
				        ClickSound.start();
			        }catch(Exception e){e.printStackTrace();}
					
					clickScore = CalculateScore(count + 1);				
				}
			}
		} else {
			if (blinkflag == 1) {
		        try{			    
			        ReduceSoundInput = AudioSystem.getAudioInputStream(urlReduceSound);
			        ReduceSound = AudioSystem.getClip();
			        ReduceSound.open(ReduceSoundInput);
			        ReduceSound.start();
		        }catch(Exception e){e.printStackTrace();}
				
		        
		        savePath(clickx,clicky);
				clicks++;
				rearrange();
				score = score + clickScore;
				blinkflag = 0;
			}
		}
		repaint();
		return true;
	}

	public void rearrange() {

		for (int i = 0; i <= 19; i++) {
			for (int j = 0; j <= 9; j++) {
				if (position[i][j] >= '1' && position[i][j] <= '5') {
					position[i][j] = '0';
				}
			}
		}
		// For height eliminate
		for (int i9 = 0; i9 <= 19; i9++) {
			havezeroX = 0;
			do {
				for (int j9 = 9; j9 >= 0; j9--) {
					if (position[i9][j9] == '0') {
						if (j9 != 0) {
							position[i9][j9] = position[i9][j9 - 1];
							position[i9][j9 - 1] = '0';
						} else {
							position[i9][j9] = '0';
						}
					}
				}
				// Find first Zero(bottom up)
				for (int j8 = 9; j8 >= 0; j8--) {
					if (position[i9][j8] == '0') {
						firstzeroX = j8;
						havezeroX = 1;
						break;
					}
				}
				// Find last ABCD(bottom up)
				for (int j7 = 9; j7 >= 0; j7--) {
					if (position[i9][j7] >= 'A' && position[i9][j7] <= 'E')
						lastABCDX = j7;
				}
				countzeroX = 0;
				for (int j6 = 9; j6 >= 0; j6--) {
					if (position[i9][j6] == '0')
						countzeroX++;
				}
				if (firstzeroX == (lastABCDX - 1) || havezeroX == 0
						|| countzeroX == 10)
					successX = 1; // dont have zero exit wihile loop
				else
					successX = 0; // have zero go to do it again

			} while (successX == 0);
		}
		// For shift left
		do {
			havezeroY = 0;
			for (int i5 = 0; i5 <= 19; i5++) {
				if (position[i5][9] == '0') {
					for (int i4 = i5; i4 <= 19; i4++) {
						for (int j5 = 0; j5 <= 9; j5++) {
							position[i4][j5] = position[i4 + 1][j5];
							position[i4 + 1][j5] = '0';
						}
					}
				}
			}
			// find the first zero(left to right)
			countzeroY = 0;
			for (int i3 = 0; i3 <= 19; i3++) {
				if (position[i3][9] == '0') {
					firstzeroY = i3;
					havezeroY = 1;
					break;
				}
			}
			// find the last ABCD(left to right)
			for (int i6 = 0; i6 <= 19; i6++) {
				if (position[i6][9] >= 'A' && position[i6][9] <= 'E') {
					lastABCDY = i6;
				}
			}
			// Find that how many zero
			// (if zero=20 that mean all off item eleminted already,finish game
			// at all)

			countzeroY = 0;
			for (int i6 = 9; i6 >= 0; i6--) {
				if (position[i6][9] == '0')
					countzeroY++;
			}
			if (firstzeroY == (lastABCDY + 1) || havezeroY == 0
					|| countzeroY == 20)
				successY = 1; // dont have zero exit wihile loop
			else
				successY = 0; // have zero go to do it again
			
		} while (successY == 0);
	}

	public int CalculateScore(int thiscount) {
		int Calculated = (thiscount - 1) * (thiscount - 1);
		return Calculated;
	}

	public void findconnect(int cx, int cy, char clickvalue) {
		switch (clickvalue) {
		case ('A'): {
			position[cx][cy] = '1';
			break;
		}
		case ('B'): {
			position[cx][cy] = '2';
			break;
		}
		case ('C'): {
			position[cx][cy] = '3';
			break;
		}
		case ('D'): {
			position[cx][cy] = '4';
			break;
		}
		case ('E'): {
			position[cx][cy] = '5';
			break;
		}
		}

		if (cx < 19 && cy >= 0 && cy <= 9) {
			if (position[cx + 1][cy] == clickvalue) {
				count++;
				findconnect(cx + 1, cy, clickvalue);
			}
		}
		if (cx > 0 && cy >= 0 && cy <= 9) {
			if (position[cx - 1][cy] == clickvalue) {
				count++;
				findconnect(cx - 1, cy, clickvalue);
			}
		}

		if (cx >= 0 && cx <= 19 && cy < 9) {
			if (position[cx][cy + 1] == clickvalue) {
				count++;
				findconnect(cx, cy + 1, clickvalue);
			}
		}

		if (cx >= 0 && cx <= 19 && cy > 0) {
			if (position[cx][cy - 1] == clickvalue) {
				count++;
				findconnect(cx, cy - 1, clickvalue);
			}
		}

		if (count == 0) {
			position[cx][cy] = clickvalue;
		} else {
			blinkflag = 1;
		}
	}

	public boolean endgame() {
		for (int i = 0; i <= 19; i++) {
			for (int j = 0; j <= 9; j++) {
				if (position[i][j] != '0') {
					if (j != 9)
						if (position[i][j + 1] == position[i][j])
							return true;
					if (i != 19)
						if (position[i + 1][j] == position[i][j])
							return true;
				}
			}
		}
		return false;
	}

	public void dbConn(int clicks, int left, int score) {
		try {
			URL url = new URL(
					"http://libront.cba.pl/highscore.php?action=submit&admin_user=libroncik&clicks="
							+ clicks
							+ "&left="
							+ left
							+ "&score="
							+ score
							+ "&access_code=4124512351235");
			InputStream in;
			in = url.openStream();
			BufferedReader b = new BufferedReader(new InputStreamReader(in));
		} catch (IOException e) {System.out.println(e.toString());}
	}
	//TODO Tracking
	public void savePath(int X, int Y){
		
	}
	public void saveBoard(char position[][]){
		
	}
	
	public static void main(String[] args) {
				
		SameGame frame = new SameGame("SameGame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	    frame.setSize(605, 380);
	    frame.setResizable(false);
	    frame.setLocation(300,200);
	    frame.setVisible(true);
		frame.init2();
		frame.repaint();		

	}

}
